home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
ddj0190.arc
/
RAHNER.EXE
/
GEN_ASM.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-21
|
9KB
|
378 lines
comment \
Sprite Circle Handler
Copyright (c) February 1989, Ryu Consulting, Inc.
(916) 722 - 1939 anytime
Written by Rahner James, CS
\
.model small, c
; ****************************************************************************
; EQUATES
; ****************************************************************************
MAX_SPRITES equ 50
; ****************************************************************************
; STRUCTURES
; ****************************************************************************
sprite_structure struc
animate_ptr dw 0,0
sprite_width dw 0 ; Width in words
sprite_height dw 0 ; Height in pixels
sprite_body db ?
sprite_structure ends
sprite_node struc
x dw 0
y dw 0
depth dw 0
pre_x dw 0
pre_y dw 0
dest_x dw 0
dest_y dw 0
adder_x dw 0
adder_y dw 0
sprite_ptr dw 0,0
next_node dw 0
sprite_node ends
.data
; ****************************************************************************
; DATA VARIABLES and EXTERNAL DEFINITIONS
; ****************************************************************************
extrn done_page_flip:byte, do_page_flip:byte
extrn min_x:word, min_y:word, max_y:word, max_x:word
first_sprite dw 0
public sprite_list
sprite_list sprite_node MAX_SPRITES dup(<>)
pre_max_x dw 639
pre_max_y dw 199
pre_min_x dw 0
pre_min_y dw 0
.code
; ****************************************************************************
; ROUTINES and EXTERNAL CODE DEFINITIONS
; ****************************************************************************
extrn do_background:near, put_sprite:near
; ****************************************************************************
;
; void DO_SPRITE_LIST( void )
; Sets up the sprites on the unviewed back page
; Given:
; A sprite list has been created and is stored in the array SPRITE_LIST
; Returns:
; If DONE_PAGE_FLIP is 0, no processing is done
; else all sprites in the sprite list are put on the non-visual page
; then DONE_PAGE_FLIP is set to 0 and DO_PAGE_FLIP is set to -1
do_sprite_list proc uses si
cmp done_page_flip, 0 ; See if we need to do this
jnz @F
jmp done
@@: call do_background
mov ax, pre_max_x
mov max_x, ax
mov ax, pre_max_y
mov max_y, ax
mov ax, pre_min_x
mov min_x, ax
mov ax, pre_min_y
mov min_y, ax
xor ax, ax ; Clear out some variables
mov pre_max_x, ax
mov pre_max_y, ax
dec ax
mov pre_min_x, ax
mov pre_min_y, ax
mov si, first_sprite ; SI -> sprite node to start with
next_sprite:
or si, si ; See if this is a NULL pointer
jnz @F
jmp almost_done
@@: mov ax, [si].x
mov [si].pre_x, ax
cmp [si].dest_x, ax ; See if we are already there
je no_add_x ; Skip if we are
mov cx, [si].dest_x ; Get our absolute value
sub cx, [si].x
jnc @F
neg cx
@@: add ax, [si].adder_x
mov [si].x, ax
sub ax, [si].dest_x
jnc @F
neg ax
@@: cmp cx, ax
jnc no_add_x
mov ax, [si].dest_x
mov [si].x, ax
no_add_x:
mov ax, [si].y
mov [si].pre_y, ax
cmp [si].dest_y, ax ; See if we are already there
je no_add_y ; Skip if we are
mov cx, [si].dest_y ; Get our absolute value
sub cx, [si].y
jnc @F
neg cx
@@: add ax, [si].adder_y
mov [si].y, ax
sub ax, [si].dest_y
jnc @F
neg ax
@@: cmp cx, ax
jnc no_add_y
mov ax, [si].dest_y
mov [si].y, ax
no_add_y:
cmp [si].y, 200 ; See if beyond bottom line
jnc pre_next_sprite
mov ax, [si].x ; See if we need to update some things
cmp ax, 640 ; See if beyond right column
jnc pre_next_sprite
cmp ax, pre_min_x ; See if pre_x < min_x
jnc @F ; Skip if not
mov pre_min_x, ax ; Update with new MIN_X
@@: mov ax, [si].y ; See if need to update min_y
cmp ax, pre_min_y
jnc @F
mov pre_min_y, ax
@@: les bx, dword ptr [si].sprite_ptr ; ES:BX -> sprite structure
mov ax, es:[bx].sprite_width
inc ax
if (@Cpu AND 2)
shl ax, 4 ; AX = AX * 16
else
rept 4
add ax, ax
endm
endif
add ax, [si].x
cmp pre_max_x, ax ; See if > max_x
jnc @F ; Jump if not
mov pre_max_x, ax ; Assume we are going to save it
@@: mov ax, es:[bx].sprite_height
add ax, [si].y
cmp pre_max_y, ax ; See if > max_x
jnc @F ; Jump if not
mov pre_max_y, ax ; Assume we are going to save it
@@: push es ; Set up for call to put_sprite()
push bx
push [si].y
push [si].x
call put_sprite
add sp, 4 ; Clear the stack
pop bx ; ES:BX -> sprite pointer
pop es
les bx, dword ptr es:[bx].animate_ptr
mov [si].sprite_ptr, bx
mov [si].sprite_ptr+2, es
pre_next_sprite:
mov si, [si].next_node ; SI -> next sprite node in line
jmp next_sprite
almost_done:
mov ax, pre_max_x
cmp ax, 640
jb @F
mov ax, 639
mov pre_max_x, ax
@@: cmp pre_min_x, ax
jb @F
dec ax
mov pre_min_x, ax
@@: mov ax, pre_max_y
cmp ax, 200
jb @F
mov ax, 199
mov pre_max_y, ax
@@: cmp pre_min_y, ax
jb @F
mov pre_min_y, ax
@@: mov done_page_flip, 0
mov do_page_flip, -1
done: ret
do_sprite_list endp
; ****************************************************************************
;
; void CLEAR_SPRITE_LIST( void )
; Zeros out the present sprite list
; Given:
; nothing
; Returns:
; FIRST_SPRITE and SPRITE_LIST array are zeroed
clear_sprite_list proc uses di
cld
mov di, offset sprite_list
mov ax, ds
mov es, ax
xor ax, ax
mov first_sprite, ax
mov cx, (MAX_SPRITES * (size sprite_node))/2
rep stosw
ret
clear_sprite_list endp
; ****************************************************************************
;
; int INSERT_SPRITE( ui X1,ui Y1, ui D_X,ui D_Y, ui PLUS_X,ui PLUS_Y,
; ui THE_DEPTH, sprite_structure far *SPRITE )
; Inserts the first sprite of a sprite circle into the linked list of circles
; Given:
; X1,Y1 = pixel location of the upper left corner of the sprite
; D_X,D_Y = pixel location of the destination of the sprite
; PLUS_X,PLUS_Y = pixels the sprite moves every page flip
; THE_DEPTH = apparent distance of the sprite from the viewer
; SPRITE -> sprite to insert
; Returns:
; If 0, sprite pointer was inserted in the array
; else !0 if there is no room
insert_sprite proc uses si, x1:word,y1:word, d_x:word,d_y:word,\
plus_x:word,plus_y:word, the_depth:word,\
sprite:dword
mov cx, MAX_SPRITES
mov bx, (offset sprite_list) - (size sprite_node)
@@: add bx, size sprite_node
mov ax, [bx].sprite_ptr ; See if this has been set yet
or ax, [bx].sprite_ptr+2
loopnz @B
jnz done_bad
les ax, sprite ; ES:AX -> sprite location
mov [bx].sprite_ptr, ax ; Save it
mov [bx].sprite_ptr+2, es
mov ax, x1 ; Set up the structure
mov [bx].x, ax
mov [bx].pre_x, ax
mov ax, y1
mov [bx].y, ax
mov [bx].pre_y, ax
mov ax, d_x
mov [bx].dest_x, ax
mov ax, d_y
mov [bx].dest_y, ax
mov ax, plus_x
mov [bx].adder_x, ax
mov ax, plus_y
mov [bx].adder_y, ax
mov ax, the_depth
mov [bx].depth, ax ; This is used in the following loop
mov dx, bx ; Save this s[rite entry for later
mov si, first_sprite ; SI -> sprite furthest from the viewer
mov bx, offset first_sprite ; BX -> previous sprite entry
mov cx, MAX_SPRITES
@@: or si, si ; See if it's a NULL ptr
jz @F ; Skip out if it is
cmp ax, [si].depth ; See if farther from observer
jnc @F
mov bx, si ; BX = this pointer
mov si, [si].next_node ; SI -> next sprite node in line
loop @B
done_bad:
mov ax, -1 ; Indicate we had a problem
jmp short done
@@: xchg si, dx ; SI -> sprite_list[i]
mov [si].next_node, dx
cmp bx, offset first_sprite
jne @F
mov [bx], si
jmp short done_good
@@: mov [bx].next_node, si
done_good:
xor ax, ax
done: ret
insert_sprite endp
; ****************************************************************************
;
; void ADD_SPRITE( sprite_structure far *DEST, far *SOURCE )
; Adds a self-relative sprite motion to the end of a sprite circle
; Given:
; DEST -> sprite circle header
; SOURCE -> sprite to add on
; Returns:
; SOURCE is added to the end of the sprite linked list and the
; circle ends are rejoined, may the circle be unbroken (ie Johnny Cash)
add_sprite proc uses si di ds, dest:dword, source:dword
lds si, dest
les di, source
next_sprite:
mov ax, [si].animate_ptr ; See if this is the end of the line
cmp ax, word ptr dest
jne @F
mov ax, [si].animate_ptr+2
cmp ax, word ptr dest+2
je got_the_end
@@: lds si, [si].animate_ptr
jmp next_sprite
got_the_end:
mov [si].animate_ptr, di
mov [si].animate_ptr+2, es
mov ax, word ptr dest
mov es:[di].animate_ptr, ax
mov ax, word ptr dest+2
mov es:[di].animate_ptr+2, ax
ret
add_sprite endp
end